{% from pinInitializerImport import makePinInitializer as makePinInitializer %}
/**
 * \file
 * \brief Definitions of low-level SPI master drivers for SPIv1 in {{ board }} ({{ dictionary['chip']['compatible'][0] }} chip)
 *
 * \author Copyright (C) 2016-2020 Kamil Szczygiel https://distortec.com https://freddiechopin.info
 *
 * \par License
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
 *
 * \warning
 * Automatically generated file - do not edit!
 */

#include "distortos/chip/spis.hpp"

#include "distortos/chip/dmas.hpp"
#include "distortos/chip/PinInitializer.hpp"
#include "distortos/chip/SpiMasterLowLevelDmaBased.hpp"
#include "distortos/chip/SpiMasterLowLevelInterruptBased.hpp"
#include "distortos/chip/STM32-SPIv1-SpiPeripheral.hpp"

#include "distortos/BIND_LOW_LEVEL_INITIALIZER.h"

/**
 * \brief Generates name of DMA channel object in the form `dma<dmaId>Channel<channelId>`.
 *
 * \param [in] dmaId is a DMA identifier
 * \param [in] channelId is a DMA channel identifier
 */

#define DMA_CHANNEL(dmaId, channelId)	CONCATENATE4(dma, dmaId, Channel, channelId)

namespace distortos
{

namespace chip
{
{% for key, spi in dictionary['SPIs'].items() if spi is mapping and 'ST,STM32-SPI-v1' in spi['compatible'] %}

#ifdef DISTORTOS_CHIP_{{ key | upper }}_ENABLE

/*---------------------------------------------------------------------------------------------------------------------+
| {{ key | upper }}
+---------------------------------------------------------------------------------------------------------------------*/

namespace
{

{% set misoPresent = 'MISO' in spi %}
{% set mosiPresent = 'MOSI' in spi %}
{% set sckPresent = 'SCK' in spi %}
{% if sckPresent != (misoPresent == True or mosiPresent == True) %}
{% raise 'Allowed combinations of pins for {}: none, {{MISO, SCK}}, {{MOSI, SCK}} or {{MISO, MOSI, SCK}}'.format(key) %}
{% endif %}
{% for pinKey in ['MISO', 'MOSI', 'SCK'] if pinKey in spi %}
{% if loop.first == True %}
/// pin initializers for {{ key | upper }}
const PinInitializer {{ key | lower }}PinInitializers[]
{
{% endif %}
		// {{ key | upper }} {{ pinKey }}
		{{ makePinInitializer(spi[pinKey]) | indent(8) | replace('    ', '\t') }}
{% if loop.last == True %}
};

{% endif %}
{% endfor %}
/**
 * \brief Low-level chip initializer for {{ key | upper }}
 *
 * This function is called before constructors for global and static objects via BIND_LOW_LEVEL_INITIALIZER().
 */

void {{ key | lower }}LowLevelInitializer()
{
#if defined(RCC_APB1ENR_{{ key | upper }}EN)
	RCC->APB1ENR |= RCC_APB1ENR_{{ key | upper }}EN;
#elif defined(RCC_APB2ENR_{{ key | upper }}EN)
	RCC->APB2ENR |= RCC_APB2ENR_{{ key | upper }}EN;
#else
	#error "Unsupported bus for {{ key | upper }}!"
#endif
{% if sckPresent == True %}

	for (auto& pinInitializer : {{ key | lower }}PinInitializers)
		pinInitializer();
{% endif %}
}

BIND_LOW_LEVEL_INITIALIZER(50, {{ key | lower }}LowLevelInitializer);

/// raw {{ key | upper }} peripheral
const SpiPeripheral {{ key | lower }}Peripheral {{ '{' }}{{ key | upper }}_BASE};

}	// namespace

#ifdef DISTORTOS_CHIP_{{ key | upper }}_DMA_BASED

SpiMasterLowLevelDmaBased {{ key | lower }}
{
		{{ key | lower }}Peripheral,
		DMA_CHANNEL(DISTORTOS_CHIP_{{ key | upper }}_RX_DMA, DISTORTOS_CHIP_{{ key | upper }}_RX_DMA_CHANNEL),
		DISTORTOS_CHIP_{{ key | upper }}_RX_DMA_REQUEST,
		DMA_CHANNEL(DISTORTOS_CHIP_{{ key | upper }}_TX_DMA, DISTORTOS_CHIP_{{ key | upper }}_TX_DMA_CHANNEL),
		DISTORTOS_CHIP_{{ key | upper }}_TX_DMA_REQUEST
};

#else	// !def DISTORTOS_CHIP_{{ key | upper }}_DMA_BASED

SpiMasterLowLevelInterruptBased {{ key | lower }} {{ '{' }}{{ key | lower }}Peripheral};

/**
 * \brief {{ spi['interrupt']['vector'] }} interrupt handler
 */

extern "C" void {{ spi['interrupt']['vector'] }}_IRQHandler()
{
	{{ key | lower }}.interruptHandler();
}

#endif	// !def DISTORTOS_CHIP_{{ key | upper }}_DMA_BASED

#endif	// def DISTORTOS_CHIP_{{ key | upper }}_ENABLE
{% endfor %}

}	// namespace chip

}	// namespace distortos
